[TJOI2015]旅游
问题描述
为了提高智商,ZJY准备去往一个新世界去旅游。这个世界的城市布局像一棵树。每两座城市之间只有一条路径可以互达。每座城市都有一种宝石,有一定的价格。ZJY为了赚取最高利益,她会选择从A城市买入再转手卖到B城市。由于ZJY买宝石时经常卖萌,因而凡是ZJY路过的城市,这座城市的宝石价格会上涨。让我们来算算ZJY旅游完之后能够赚取的最大利润。(如a城市宝石价格为v,则ZJY出售价格也为v)
输入格式
第一行输入一个正整数N,表示城市个数。
接下来一行输入N个正整数表示每座城市宝石的最初价格p,每个宝石的初始价格不超过100。
第三行开始连续输入N-1行,每行有两个数字x和y。表示x城市和y城市有一条路径。城市编号从1开始。
下一行输入一个整数Q,表示询问次数。
接下来Q行,每行输入三个正整数a,b,v,表示ZJY从a旅游到b,城市宝石上涨v。
即是询问a—>b(有方向)间路径上的max(Price[j]−Price[i])) 且j到a的距离比i到a大 。然后把这条路径上所有点的点权+v。
输出格式
对于每次询问,输出ZJY可能获得的最大利润,如果亏本则输出0。
数据范围
1≤ N≤50000, 1≤Q ≤50000
首先考虑一条链的情况怎么做。
区间整体加,这提示我们可以用线段树维护。容易想到维护区间最大值、区间最小值、$max($右边-左边$)$、$max($左边-右边$)$。$max($右边-左边$)$的值由左儿子的$max($右边-左边$)$、右儿子的$max($右边-左边$)$、右儿子最大值-左儿子最小值共同决定。$max($左边-右边$)$同理。
询问一段区间,只需要把线段树上对应区间取出来按照上述规则合并,判断方向之后决定取$max($右边-左边$)$还是$max($左边-右边$)$即可。
问题扩展到树上时,显然使用树链剖分,线段树维护相同的值,只不过要把路径拆成$u->LCA$、$LCA->v$两段分别处理,注意方向。
把线段树节点开成结构体形式或许方便实现。
1 |
|